using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Text;
using System.Windows.Forms;

namespace YourNamespace.WinControls
{
    public partial class RTFEditor : UserControl
    {
        public new event EventHandler TextChanged;

        private enum BulletType
        {
            None = 1,
            Bullet = 2,
            Number = 3,
            Letter = 4,
            CapitalLetter = 5,
            Roman = 6,
            BigRoman = 7,
            Max = BigRoman,
        }

        private BulletType _currentBulletType = BulletType.None;

        public RTFEditor()
        {
            InitializeComponent();


            // HACK:  not sure why, but in VS2005 the design time setting is ignored
            this.BackColor = Color.FromKnownColor(KnownColor.Control);
            
            this.toolBar1.ButtonClick += new ToolBarButtonClickEventHandler(toolBar1_ButtonClick);
            this.richTextBox1.TextChanged += new EventHandler(richTextBox1_TextChanged);
        }        

        void richTextBox1_TextChanged(object sender, EventArgs e)
        {
            if (TextChanged != null)
                TextChanged(sender, e);
        }

        private void SetFont(bool bold, bool italic, bool underline, bool strikeout)
        {
            if (richTextBox1.SelectionFont != null)
            {
                System.Drawing.Font currentFont = richTextBox1.SelectionFont;
                System.Drawing.FontStyle newFontStyle = FontStyle.Regular;
                              
                if (bold == true)
                    newFontStyle |= FontStyle.Bold;
                if (italic == true)
                    newFontStyle |= FontStyle.Italic;
                if (underline == true)
                    newFontStyle |= FontStyle.Underline;
                if (strikeout == true)
                    newFontStyle |= FontStyle.Strikeout;
                
                richTextBox1.SelectionFont = new Font(currentFont.FontFamily,
                   currentFont.Size, newFontStyle);
            }
        }

        private void toolBar1_ButtonClick(object sender, ToolBarButtonClickEventArgs e)
        {
            try
            {
                switch (e.Button.Tag.ToString())
                {
                    case "TextCut":
                        if (richTextBox1.SelectedText != null && richTextBox1.SelectedText.Length > 0)
                        {
                            Clipboard.SetDataObject(this.richTextBox1.SelectedText, true);
                            this.richTextBox1.SelectedText = "";
                        }
                        break;
                    case "TextCopy":
                        Clipboard.SetDataObject(this.richTextBox1.SelectedText, true);
                        break;
                    case "TextPaste":
                        IDataObject data = Clipboard.GetDataObject();
                        if (data != null && data.GetDataPresent(DataFormats.Text))
                        {
                            if (this.richTextBox1.SelectedText == null || this.richTextBox1.SelectedText.Length == 0)
                            {
                                int pos = this.richTextBox1.SelectionStart;
                                this.richTextBox1.Text = this.richTextBox1.Text.Insert(pos, (string)data.GetData(DataFormats.Text));
                                this.richTextBox1.SelectionStart = pos;
                            }
                            else
                            {
                                this.richTextBox1.SelectedText = (string)data.GetData(DataFormats.Text);
                            }
                        }
                        break;
                    case "EditUndo":
                        this.richTextBox1.Undo();
                        break;
                    case "EditRedo":
                        this.richTextBox1.Redo();
                        break;
                    case "FormatBold":                        
                        if (richTextBox1.SelectionFont != null)
                        {
                            System.Drawing.Font currentFont = richTextBox1.SelectionFont;
                            SetFont(!currentFont.Bold, currentFont.Italic, currentFont.Underline, currentFont.Strikeout);                            
                        }
                        break;
                    case "FormatUnderline":
                        if (richTextBox1.SelectionFont != null)
                        {
                            System.Drawing.Font currentFont = richTextBox1.SelectionFont;
                            SetFont(currentFont.Bold, currentFont.Italic, !currentFont.Underline, currentFont.Strikeout);
                        }
                        break;
                    case "FormatItalic":
                        if (richTextBox1.SelectionFont != null)
                        {
                            System.Drawing.Font currentFont = richTextBox1.SelectionFont;
                            SetFont(currentFont.Bold, !currentFont.Italic, currentFont.Underline, currentFont.Strikeout);
                        }
                        break;
                    case "FontDialog":
                        FontDialog fontDlg = new FontDialog();
                        fontDlg.Font = this.richTextBox1.SelectionFont;
                        if (fontDlg.ShowDialog() == DialogResult.OK)
                        {
                            this.richTextBox1.SelectionFont = fontDlg.Font;
                        }
                        break;
                    case "ColorDialog":
                        ColorDialog colorDlg = new ColorDialog();
                        colorDlg.Color = this.richTextBox1.SelectionColor;
                        if (colorDlg.ShowDialog() == DialogResult.OK)
                        {
                            this.richTextBox1.SelectionColor = colorDlg.Color;
                        }
                        break;
                    case "JustifyLeft":
                        this.richTextBox1.SelectionAlignment = HorizontalAlignment.Left;
                        break;
                    case "JustifyCenter":
                        this.richTextBox1.SelectionAlignment = HorizontalAlignment.Center;
                        break;
                    case "JustifyRight":                        
                        this.richTextBox1.SelectionAlignment = HorizontalAlignment.Right;
                        break;
                    case "FontIndent":
                        this.richTextBox1.SelectionIndent += 20;
                        break;
                    case "FontOutdent":
                        this.richTextBox1.SelectionIndent -= 20;
                        if (this.richTextBox1.SelectionIndent < 0)
                            this.richTextBox1.SelectionIndent = 0;
                        break;
                    case "ListOrdered":
                        {
                            this.richTextBox1.Focus();

                            int cycles = 0;

                            if (_currentBulletType == BulletType.None)
                                cycles = BulletType.Number - BulletType.None;
                            else if (_currentBulletType == BulletType.Number)
                                cycles = BulletType.Max - BulletType.Number + 1;
                            else if (_currentBulletType == BulletType.Bullet)
                                cycles = BulletType.Number - BulletType.Bullet;

                            for (int cnt = 0; cnt < cycles; cnt++)
                            {
                                SendKeys.Send("^+L");
                            }

                            if (_currentBulletType != BulletType.Number)
                                _currentBulletType = BulletType.Number;
                            else
                                _currentBulletType = BulletType.None;
                        }
                        break;
                    case "ListUnordered":
                        {
                            this.richTextBox1.Focus();

                            int cycles = 0;

                            if (_currentBulletType == BulletType.None)
                                cycles = BulletType.Bullet - BulletType.None;
                            else if (_currentBulletType == BulletType.Bullet)
                                cycles = BulletType.Max - BulletType.Bullet + 1;
                            else if (_currentBulletType == BulletType.Number)
                                cycles = BulletType.Max - BulletType.Number + (int) BulletType.Bullet;

                            for (int cnt = 0; cnt < cycles; cnt++)
                            {
                                SendKeys.Send("^+L");
                            }

                            if (_currentBulletType != BulletType.Bullet)
                                _currentBulletType = BulletType.Bullet;
                            else
                                _currentBulletType = BulletType.None;
                        }
                        break;                   
                }
            }
            catch (AMN.Services.Infrastructure.Exceptions.AMNException)
            {
                throw;
            }            
            catch (Exception ex)
            {
                throw new AMN.Services.Infrastructure.Exceptions.AMNException("RTF toolbar error", new object[] { e.Button.Tag }, ex);
            }

            // ensure textbox has the focus after command execution
            this.richTextBox1.Focus();       
        }
                
        public Point ToolBarLocation
        {
            get { return this.toolBar1.Location; }
            set { this.toolBar1.Location = value; }
        }

        protected override void OnResize(EventArgs e)
        {
            base.OnResize(e);

            // HACK:  The Anchor on RichTextBox is letting me down...  It's not resizing properly 
            //        (the RTF is much larger than the control)
            this.richTextBox1.Width = this.Width;
            this.richTextBox1.Height = this.Height - this.richTextBox1.Top;
        }

        public override string Text
        {
            get { return this.richTextBox1.Rtf; }
            set
            {
                // First, make sure it is RTF
                if (value == null)
                    this.richTextBox1.Text = "";
                else if (value.IndexOf("\\rtf1\\") == -1)
                    this.richTextBox1.Text = value;
                else
                    this.richTextBox1.Rtf = value;
            }
        }
    }
}
